package com.tg.app.activity.device.add;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;

import com.base.BaseActivity;
import com.inuker.bluetooth.library.ClientManager;
import com.inuker.bluetooth.library.connect.listener.BluetoothStateListener;
import com.inuker.bluetooth.library.search.SearchRequest;
import com.inuker.bluetooth.library.search.SearchResult;
import com.inuker.bluetooth.library.search.response.SearchResponse;
import com.tange.base.toolkit.AppUtil;
import com.tange.base.toolkit.StringUtils;
import com.tange.base.toolkit.TGThreadPool;
import com.tange.module.core.wifi.scan.WiFiScanManager;
import com.tg.app.BuildConfig;
import com.tg.app.R;
import com.tg.app.adapter.BluetoothDeviceAdapter;
import com.tg.appcommon.android.DialogUtil;
import com.tg.appcommon.android.PermissionUtil;
import com.tg.appcommon.android.ResourcesUtil;
import com.tg.appcommon.android.TGLog;
import com.tg.data.helper.DeviceTypeHelper;

import java.util.ArrayList;

public class SelectBluetoothDeviceActivity extends BaseActivity implements  View.OnClickListener {
    public static final String TAG ="SelectBluetoothDeviceActivity";
    private static final int TIMEOUT_MAX = 30000;
    private BluetoothDeviceAdapter deviceAdapter;
    private final ArrayList<SearchResult> mDevices = new ArrayList<>();
    private boolean isAutoConnected = false;
    private ImageView imageView;
    private boolean isRequestPermissions = false;

    private TextView tvTextView;
    private Button mButton;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);//remove title bar  即隐藏标题栏
        setContentView(R.layout.activity_select_bluetooth);
        hideActionBar();
        TGLog.d(TAG, "onCreate initView");
        initView();
    }

    private final BluetoothStateListener mBluetoothStateListener = new BluetoothStateListener() {
        @Override
        public void onBluetoothStateChanged(boolean openOrClosed) {
            imageView.setVisibility(openOrClosed? View.VISIBLE : View.GONE);
            findViewById(R.id.ll_open_bluetooth).setVisibility(openOrClosed? View.GONE : View.VISIBLE);
            TGLog.d(TAG, "MainActivity.openOrClosed = " + openOrClosed);
            if (openOrClosed){
                startSearch();
            }
        }
    };

    private final SearchResponse mSearchResponse = new SearchResponse() {
        @Override
        public void onSearchStarted() {
            TGLog.d(TAG, "MainActivity.onSearchStarted");
            mDevices.clear();
        }

        @Override
        public void onDeviceFounded(SearchResult device) {
            TGLog.d(TAG, "onDeviceFounded = " +  device + ", ap_prefix = " + BuildConfig.DEVICE_AP_PREFIX);
            if (device != null){
                TGLog.d(TAG, "onDeviceFounded name = " + device.getName() + ", address = " + device.getAddress() + "， mDevices.size = " + mDevices.size());
                if (device.getName().startsWith(BuildConfig.DEVICE_AP_PREFIX)){
                    if (!mDevices.contains(device)) {
                        mDevices.add(device);
                        deviceAdapter.notifyDataSetChanged();
                    }
                }
            }
            if (mDevices.size() > 0){
                TGThreadPool.executeOnUiThread(() -> imageView.setVisibility(View.GONE));

                TGThreadPool.executeOnUiThreadDelayed(() -> {
                    if (mDevices.size() == 1 && !isAutoConnected && !AppUtil.isActivityFinishingOrDestroyed(SelectBluetoothDeviceActivity.this)) {
                        SearchResult searchResult = mDevices.get(0);
                        goToBluetoothDeviceSetWifiActivity(searchResult);
                    }
                }, 5000);
            }
        }

        @Override
        public void onSearchStopped() {
            TGLog.d(TAG, "MainActivity.onSearchStopped");
            if (mDevices.size() == 0){
                scanLeDevice();
            }
        }

        @Override
        public void onSearchCanceled() {
            TGLog.d(TAG,"MainActivity.onSearchCanceled");
            if (mDevices.size() == 0){
                scanLeDevice();
            }
        }
    };


    private final BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            //对扫描到的设备进行处理，可以依据BluetoothDevice中的信息、信号强度rssi以及广播包和响应包组成的scanRecord字节数组进行分析
            if (device != null){
                TGLog.d(TAG, "onLeScan name = " + device.getName() + ", address = " + device.getAddress() + "， mDevices.size = " + mDevices.size());
                if (!StringUtils.isEmpty(device.getName()) && device.getName().startsWith(BuildConfig.DEVICE_AP_PREFIX)){
                    boolean add = true;
                    if (mDevices.size() > 0){
                        if (StringUtils.equalsIgnoreCase(mDevices.get(0).getName(), device.getName()) && StringUtils.equalsIgnoreCase(device.getAddress(), mDevices.get(0).getAddress())){
                            add  = false;
                        }
                    }
                    if (add){
                        SearchResult searchResult = new SearchResult(device, rssi, scanRecord);
                        mDevices.add(searchResult);
                        deviceAdapter.notifyDataSetChanged();
                    }
                }
            }
            if (mDevices.size() > 0){
                TGThreadPool.executeOnUiThread(() -> imageView.setVisibility(View.GONE));
                TGThreadPool.executeOnUiThreadDelayed(() -> {
                    if (mDevices.size() == 1 && !isAutoConnected && !AppUtil.isActivityFinishingOrDestroyed(SelectBluetoothDeviceActivity.this)) {
                        SearchResult searchResult = mDevices.get(0);
                        goToBluetoothDeviceSetWifiActivity(searchResult);
                    }
                }, 5000);

            }
        }
    };

    private void startLeScan(){
        TGLog.d(TAG, "startLeScan");
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
        bluetoothAdapter.startLeScan(mLeScanCallback);
    }

    private void stopLeScan(){
        TGLog.d(TAG, "stopLeScan");
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
        bluetoothAdapter.stopLeScan(mLeScanCallback);
    }

    private void scanLeDevice() {
        TGThreadPool.executeDelay(this::stopLeScan, 10000);
        startLeScan();
    }


    @Override
    public boolean shouldSetStatusBarColor() {
        return true;
    }

    private void stopSearch(){
        stopLeScan();
        ClientManager.getClient().stopSearch();
    }

    private void goToBluetoothDeviceSetWifiActivity(SearchResult searchResult){
        isAutoConnected = true;
        stopSearch();
        String mUUID = String.format("and_%s", StringUtils.getRandomStr(5));
        TGLog.d(TAG, "goToBluetoothDeviceSetWifiActivity isAutoConnected = " + isAutoConnected + "， mUUID = " + mUUID);
        Intent intent = new Intent(SelectBluetoothDeviceActivity.this, BluetoothDeviceSetWifiActivity.class);
        intent.putExtra(ApSetWifiActivityEx.EXT_UUID, mUUID);
        intent.putExtra(ApSetWifiActivityEx.EXT_WIFI_UUID, mUUID);
        intent.putExtra(ApSetWifiActivityEx.EXT_DEVICE_BLUETOOTH, searchResult);
        intent.putExtra(ApSetWifiActivityEx.EXT_DEVICE_TYPE, DeviceTypeHelper.DEVICE_LOCKBELL);
        startActivity(intent);
        finish();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        TGLog.d(TAG, "onRequestPermissionsResult");

        if (requestCode == AddFragmentTabActivity.PERMISSON_REQUESTCODE) {
            isRequestPermissions = true;
            if (PermissionUtil.verifyPermissions(grantResults)) {      //没有授权
                TGLog.d(TAG, "授权成功");
            }else{
                for (int result : grantResults) {
                    if (result != PackageManager.PERMISSION_GRANTED) {
                        TGLog.d(TAG, "没有授权：" + result);
                    }
                }
            }
            search();
        }
    }

    @Override
    protected void onResume(){
        super.onResume();
        TGLog.d(TAG, "onResume");
        if (WiFiScanManager.scanner().isLocationEnabled(this)){
            boolean isLocationGranted = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
            boolean isBluetoothOpened = ClientManager.getClient().isBluetoothOpened();
            TGLog.d(TAG, "isLocationGranted  = " + isLocationGranted + ", version = " + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M));
            if (!isLocationGranted) {
                LocationGrantGuideActivity.launch(this);
            }else {
                TGLog.d(TAG, "isBluetoothOpened  = " + isBluetoothOpened);
                if (isBluetoothOpened){
                    startSearch();
                }
            }
            ClientManager.getClient().registerBluetoothStateListener(mBluetoothStateListener);
        }else{
            DialogUtil.openGpsService(this);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        ClientManager.getClient().stopSearch();
    }

    private boolean checkPermissions(){
        String[] permission = {
                "android.permission.BLUETOOTH_SCAN",
                "android.permission.BLUETOOTH_ADVERTISE",
                "android.permission.BLUETOOTH_CONNECT"};
        PermissionUtil permissionUtil = new PermissionUtil(this);
        return (permissionUtil.checkPermissions(this, AddFragmentTabActivity.PERMISSON_REQUESTCODE, permission));
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        TGLog.d(TAG, "requestCode == " + requestCode + ", resultCode " + resultCode);
        if (requestCode == LocationGrantGuideActivity.REQUEST_CODE) {
            if (resultCode == RESULT_CANCELED) {
                finish();
            } else if (resultCode == RESULT_OK) {
                startSearch();
            }
        }
    }

    @Override
    protected void initView() {
        ListView listView = findViewById(R.id.device_add_ap_camera_list);
        imageView = findViewById(R.id.icon_device_ap_add_search);
        tvTextView = findViewById(R.id.cb_message_filter_device_all);
        mButton = findViewById(R.id.hear_tips_button);
        findViewById(R.id.back_toolbar).setOnClickListener(v -> finish());

        boolean isBluetoothOpened = ClientManager.getClient().isBluetoothOpened();
        imageView.setVisibility(isBluetoothOpened? View.VISIBLE : View.GONE);
        findViewById(R.id.ll_open_bluetooth).setVisibility(isBluetoothOpened? View.GONE : View.VISIBLE);

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String text = mButton.getText().toString();
                if (StringUtils.equalsIgnoreCase(text, ResourcesUtil.getString(R.string.startup_bluetooth))){
                    ClientManager.getClient().openBluetooth();
                }else{
                    findViewById(R.id.ll_open_bluetooth).setVisibility(View.GONE);
                    imageView.setVisibility(View.VISIBLE);
                    search();

                }
            }
        });
        deviceAdapter = new BluetoothDeviceAdapter(mDevices,this);
        listView.setAdapter(deviceAdapter);
        listView.setOnItemClickListener((parent, view, position, id) -> {
            if (mDevices.size() > 0 && position >= 0 && position < mDevices.size()){
                SearchResult searchResult = mDevices.get(position);
                TGLog.d(TAG, "getName:" + searchResult.getName() + ", getAddress:" + searchResult.getAddress());
                goToBluetoothDeviceSetWifiActivity(searchResult);
            }
        });
    }

    private void startSearch() {
        if (isRequestPermissions){
            search();
        }else{
            if (checkPermissions()) {
                isRequestPermissions = true;
                TGLog.d(TAG, "startSearch -- yes");
                search();
            }else{
                TGLog.d(TAG, "startSearch no");
            }
        }

    }

    private void showReSearchUI(){
        findViewById(R.id.ll_open_bluetooth).setVisibility(View.VISIBLE);
        tvTextView.setText(R.string.device_not_found);
        mButton.setText(R.string.add_device_research);
        imageView.setVisibility(View.GONE);
    }

    private void search() {
        TGLog.d(TAG, "startSearch -- search");
        SearchRequest request = new SearchRequest.Builder().searchBluetoothLeDevice(3000).searchBluetoothClassicDevice(5000).searchBluetoothLeDevice(2000).build();
        ClientManager.getClient().search(request, mSearchResponse);

        TGThreadPool.executeOnUiThreadDelayed(() -> {
            if (mDevices.size() == 0){
                stopSearch();
                showReSearchUI();
            }
        }, TIMEOUT_MAX);
    }



    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    public void onClick(View v) {
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ClientManager.getClient().stopSearch();
        ClientManager.getClient().unregisterBluetoothStateListener(mBluetoothStateListener);
    }
}

